package fr.capsuleaube.android.fragment;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import java.util.ArrayList;

import fr.capsuleaube.android.R;
import fr.capsuleaube.android.bean.Producteur;
import fr.capsuleaube.android.utils.Consts;
import fr.capsuleaube.android.utils.PageDownloader;

public class ProducteurListFragment extends ListFragment {

    // Listener implémenté dans l'activité lorsqu'un producteur est choisi
    private OnProducteurSelectedListener mOnProducteurSelectedListener;

    // Adapter associé à la ListView contenant les producteurs
    private ProducteurListAdapter mProducteurListAdapter;

    // Contient la liste de tous les producteurs obtenus lors du chargement de l'application
    // Liste reduite lorsqu'il s'agit d'une recherche
    private ArrayList<Producteur> mProducteursFullList = new ArrayList<Producteur>();

    // Utilisé pour afficher un message d'erreur à l'utilisateur
    // Positionné à vrai lorsque la requête HTTP a échouée
    private boolean mConnectionError = false;

    // Ensemble des vue utilisée dans les différents scénarios d'utilisation
    private View mMainView;
    private View mLoadingView;
    private View mNetworkErrorView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // Vide si l'utilisateur n'a pas effectué de recherche
        String lSearchQuery = "";

        // Récupération de la recherche effectuée par l'utilisateur
        Bundle args = getArguments();
        if (args != null) {
            lSearchQuery = args.getString(Consts.PRODUCTEUR_QUERY);
        }

        View lView = inflater.inflate(R.layout.producteurlist_fragment, container, false);

        // Instanciation de la View principale
        mMainView = lView.findViewById(R.id.producteur_list_mainview);

        // Instanciation de la LoadingView et de l'ErrorView
        mLoadingView = lView.findViewById(R.id.producteur_list_loading);
        mNetworkErrorView = lView.findViewById(R.id.producteur_list_network_error);

        mProducteurListAdapter = new ProducteurListAdapter(inflater.getContext());
        setListAdapter(mProducteurListAdapter);

        if (mProducteursFullList.isEmpty()) {

            if (savedInstanceState != null && !savedInstanceState.getBoolean("mConnectionError") && savedInstanceState.getParcelableArrayList("mProducteursFullList") != null) {
                // Lors d'un changement de configuration (rotation de l'écran par exemple)
                mProducteursFullList = savedInstanceState.getParcelableArrayList("mProducteursFullList");

                mProducteurListAdapter.setListItems(mProducteursFullList);
                mProducteurListAdapter.notifyDataSetChanged();

                displayMainView();
            } else {
                new ProducteurListDownloader().execute(lSearchQuery);
            }
        } else {
            // Fragment créé ou restauré
            mProducteurListAdapter.setListItems(mProducteursFullList);
            mProducteurListAdapter.notifyDataSetChanged();

            displayMainView();
        }

        return lView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        String lSearchQuery = "";
        // Récupération de la recherche effectuée par l'utilisateur
        Bundle args = getArguments();
        if (args != null) {
            lSearchQuery = args.getString(Consts.PRODUCTEUR_QUERY);
        }

        // Permet l'instanciation de l'ActionBar
        setHasOptionsMenu(true);
        ActionBar lActionBar = ((ActionBarActivity) getActivity()).getSupportActionBar();
        if (lSearchQuery.equals("")) {
            lActionBar.setTitle("Capsule Aube");
            lActionBar.setSubtitle("Sélectionnez un producteur...");
        } else {
            lActionBar.setDisplayHomeAsUpEnabled(true);
            lActionBar.setTitle("Capsule Aube");
            lActionBar.setSubtitle("Résultats pour : " + lSearchQuery.substring(1, lSearchQuery.length() - 1));
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // Inflate the menu items for use in the action bar
        inflater.inflate(R.menu.producteurlist_actionbar, menu);

        SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        if (searchItem != null) {
            SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
        }

    }

    @Override
    public void onListItemClick(ListView list, View view, int position, long id) {

        // On récupére l'objet du producteur sélectionné
        Producteur producteur = mProducteursFullList.get(position);
        mOnProducteurSelectedListener.onProducteurSelected(producteur);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mOnProducteurSelectedListener = (OnProducteurSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement listener");
        }
    }

    @Override
    public void onSaveInstanceState(Bundle pOutState) {
        super.onSaveInstanceState(pOutState);
        if (mProducteursFullList != null && !mProducteursFullList.isEmpty()) {
            pOutState.putParcelableArrayList("mProducteursFullList", mProducteursFullList);
        }
        pOutState.putBoolean("mConnectionError", mConnectionError);
    }

    private void displayMainView() {
        mNetworkErrorView.setVisibility(View.GONE);
        mLoadingView.setVisibility(View.GONE);
        mMainView.setVisibility(View.VISIBLE);
    }

    private void displayNetworkErrorView() {
        mLoadingView.setVisibility(View.GONE);
        mMainView.setVisibility(View.GONE);
        mNetworkErrorView.setVisibility(View.VISIBLE);
    }

    public interface OnProducteurSelectedListener {
        public void onProducteurSelected(Producteur pProducteur);
    }

    private class ProducteurListDownloader extends AsyncTask<String, Void, ArrayList<Producteur>> {

        @Override
        protected ArrayList<Producteur> doInBackground(String... pSearchPatterns) {

            String lSearchPattern = pSearchPatterns[0];

            if (lSearchPattern == null || lSearchPattern.length() == 0) {
                lSearchPattern = "%";
            }

            PageDownloader lPageDL = new PageDownloader();
            String[] lReqParams = new String[]{"http://www.capsuleaube.fr/rechercheAndroidID.php", "GET", "name=" + lSearchPattern};
            String lPageContent;

            try {
                lPageContent = lPageDL.download(lReqParams);
            } catch (Exception e) {
                mConnectionError = true;
                return null;
            }

            String[] lProducteurStringArray = lPageContent.split("\n");
            ArrayList<Producteur> lProducteursList = new ArrayList<Producteur>();

            // Test s'il y a au moins un résultat
            if (lProducteurStringArray[0].length() != 0) {

                // Si oui, on parse les résultats.
                for (String s : lProducteurStringArray) {
                    Producteur lProducteur = new Producteur();
                    String[] lSplitInfo = s.split("\\^");

                    if (lSplitInfo.length >= 0) {
                        if (lSplitInfo.length >= 2) {

                            if (lSplitInfo[1] != null && lSplitInfo[1].length() > 0) {
                                lProducteur.setVillage(lSplitInfo[1]);
                            }
                        }

                        if (lSplitInfo[0] != null && lSplitInfo[0].length() > 0) {
                            lProducteur.setNom(lSplitInfo[0]);
                        }

                        lProducteursList.add(lProducteur);
                    }
                }
            }
            return lProducteursList;
        }

        protected void onPostExecute(ArrayList<Producteur> pProducteurArraylist) {

            if (!mConnectionError) {
                if (!pProducteurArraylist.isEmpty()) {
                    mProducteursFullList.addAll(pProducteurArraylist);
                    mProducteurListAdapter.setListItems(mProducteursFullList);
                    mProducteurListAdapter.notifyDataSetChanged();

                    // Hack : la dernière version d'android est buggée, permet de forcer le FastScroll
                    // Si je ne l'utilise pas le FastScroll n'apparait qu'apres une rotation ou de la
                    // sélection d'un champ texte...
                    // https://code.google.com/p/android/issues/detail?id=63545
                    if (Build.VERSION.SDK_INT >= 19) {
                        getListView().setFastScrollAlwaysVisible(true);
                    }

                    displayMainView();
                } else {
                    // S'il n'y a aucun résultat à la recherche
                    AlertDialog.Builder lNoResultAlertDialogBuilder = new AlertDialog.Builder(getActivity());
                    lNoResultAlertDialogBuilder.setTitle("Résultat");
                    lNoResultAlertDialogBuilder.setCancelable(false);
                    lNoResultAlertDialogBuilder.setMessage(R.string.aucun_resultat);
                    lNoResultAlertDialogBuilder.setNegativeButton("OK", new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            getActivity().finish();
                        }
                    });

                    AlertDialog lAlertDialog = lNoResultAlertDialogBuilder.create();
                    lAlertDialog.show();
                }
            } else {
                displayNetworkErrorView();
            }
        }
    }
}
